﻿using System;
using System.Transactions;
using System.Web.UI.WebControls;
using DotNetNuke.Modules._2DoTasks.Components;
using DotNetNuke.Modules._2DoTasks.Components.Controllers;
using DotNetNuke.Modules._2DoTasks.Components.Entities;
using DotNetNuke.Modules._2DoTasks.Components.ExceptionHandling;
using DotNetNuke.Services.Exceptions;
using DotNetNuke.Services.Localization;

namespace DotNetNuke.Modules._2DoTasks
{
    public partial class TaskSubTasks : _2DoTasksModuleBase
    {
        #region "Properties"

        private Nullable<int> SubTaskId
        {
            get
            {
                if (ViewState["TaskSubTasks_SubTaskId"] != null)
                    return Convert.ToInt32(ViewState["TaskSubTasks_SubTaskId"]);
                return null;
            }
            set
            {
                ViewState["TaskSubTasks_SubTaskId"] = value;
            }
        }

        /// <summary>
        /// Property for the task name info
        /// </summary>
        public string TaskName
        {
            get
            {
                string subTask = txt_subTask.Text.Trim();
                if (subTask.Equals(string.Empty))
                    throw new ParameterValidationException(Localization.GetString("ValidationTaskNameRequired", this.LocalResourceFile));
                return subTask;
            }
            set
            {
                txt_subTask.Text = value;
            }
        }

        #endregion "Properties"

        #region "Events"

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                FillLanguages();
                Messages.ClearMessages();

                //Implement your edit logic for your module
                if (!Page.IsPostBack)
                {
                    if (TaskId.HasValue)
                    {
                        BindTaskSubTasks(TaskId.Value);
                    }
                }
            }
            catch (Exception exc) //Module failed to load
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }

        protected void lst_subtasks_LayoutCreated(object sender, EventArgs e)
        {
        }

        protected void lst_subtasks_ItemDataBound(object sender, System.Web.UI.WebControls.ListViewItemEventArgs e)
        {
            if (e.Item.ItemType == ListViewItemType.DataItem)
            {
                var lnk_edit = e.Item.FindControl("lnk_edit") as LinkButton;
                var lnk_delete = e.Item.FindControl("lnk_delete") as LinkButton;

                var curTask = (_TaskSubTask)e.Item.DataItem;

                if (lnk_edit != null && lnk_delete != null)
                {
                    lnk_edit.CommandArgument = curTask.Id.ToString();
                    lnk_delete.CommandArgument = curTask.Id.ToString();

                    DotNetNuke.UI.Utilities.ClientAPI.AddButtonConfirm(lnk_delete, Localization.GetString("DeleteConfirm", this.LocalResourceFile));
                }
            }
        }

        /// <summary>
        /// Clears the controls for update/add task
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btn_clearTask_Click(object sender, EventArgs e)
        {
            ClearSubTaskControl();
        }

        /// <summary>
        /// Adds a new sub task
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btn_addTask_Click(object sender, EventArgs e)
        {
            try
            {
                using (UnitOfWork uof = new UnitOfWork(PortalId, ModuleId))
                {
                    TaskSubTaskController taskSubTaskController = new TaskSubTaskController(uof, TaskId.Value);
                    TaskController taskController = new TaskController(uof);
                    _Task task = taskController.Get(TaskId.Value);

                    _TaskSubTask taskSubTask = new _TaskSubTask
                    {
                        Name = TaskName,
                        AssignedUserId = task.AssignedUserId
                    };

                    using (TransactionScope scope = new TransactionScope())
                    {
                        if (SubTaskId.HasValue)
                        {
                            taskSubTask.Id = SubTaskId.Value;
                            taskSubTaskController.Update(taskSubTask);
                        }
                        else
                            taskSubTaskController.Add(taskSubTask);

                        scope.Complete();
                    }

                    if (SubTaskId.HasValue)
                        Messages.ShowSuccess(Localization.GetString("UpdateSuccess", this.LocalResourceFile));
                    else
                        Messages.ShowSuccess(Localization.GetString("AddSuccess", this.LocalResourceFile));

                    ClearSubTaskControl();
                    FillTaskSubTasks(uof, taskSubTaskController);
                }
            }
            catch (ParameterValidationException exc)
            {
                Messages.ShowWarning(exc.Message);
            }
            catch (TaskTimeValidationException exc)
            {
                if (exc.StateOfError() == SharedEnum.CrudState.Insert)
                {
                    TaskSubTaskController.InsertStatus status =
                        (TaskSubTaskController.InsertStatus)Enum.Parse(typeof(TaskSubTaskController.InsertStatus), exc.ErrorCode().ToString());

                    switch (status)
                    {
                        case TaskSubTaskController.InsertStatus.TASKNOTFOUND:
                            Messages.ShowWarning(Localization.GetString("WarningTASKNOTFOUND", this.LocalResourceFile));
                            break;

                        //case TaskSubTaskController.InsertStatus.ASSIGNEDNOTMEMBER:
                        //    Messages.ShowWarning(Localization.GetString("WarningASSIGNEDNOTMEMBER", this.LocalResourceFile));
                        //    break;

                        case TaskSubTaskController.InsertStatus.CREATORNOTMEMBER:
                            Messages.ShowWarning(Localization.GetString("WarningCREATORNOTMEMBER", this.LocalResourceFile));
                            break;

                        //case TaskSubTaskController.InsertStatus.INVALIDASSIGNEDUSER:
                        //    Messages.ShowWarning(Localization.GetString("WarningINVALIDASSIGNEDUSER", this.LocalResourceFile));
                        //    break;

                        case TaskSubTaskController.InsertStatus.INVALIDCREATIONUSER:
                            Messages.ShowWarning(Localization.GetString("WarningINVALIDCREATIONUSER", this.LocalResourceFile));
                            break;

                        case TaskSubTaskController.InsertStatus.SUBTASKNOTVALID:
                            Messages.ShowWarning(Localization.GetString("WarningSUBTASKNOTVALID", this.LocalResourceFile));
                            break;

                        default:
                            Exceptions.LogException(exc);
                            Messages.ShowError(Localization.GetString("ErrorAddTaskSubTask", this.LocalResourceFile));
                            break;
                    }
                }
                else if (exc.StateOfError() == SharedEnum.CrudState.Update)
                {
                    TaskSubTaskController.UpdateStatus status =
                        (TaskSubTaskController.UpdateStatus)Enum.Parse(typeof(TaskSubTaskController.UpdateStatus), exc.ErrorCode().ToString());

                    switch (status)
                    {
                        case TaskSubTaskController.UpdateStatus.TASKNOTFOUND:
                            Messages.ShowWarning(Localization.GetString("WarningTASKNOTFOUND", this.LocalResourceFile));
                            break;

                        //case TaskSubTaskController.UpdateStatus.ASSIGNEDNOTMEMBER:
                        //    Messages.ShowWarning(Localization.GetString("WarningASSIGNEDNOTMEMBER", this.LocalResourceFile));
                        //    break;

                        case TaskSubTaskController.UpdateStatus.LASTCHANGEUSERNOTMEMBER:
                            Messages.ShowWarning(Localization.GetString("WarningLASTCHANGEUSERNOTMEMBER", this.LocalResourceFile));
                            break;

                        case TaskSubTaskController.UpdateStatus.ONLYCREATORCANCHANGE:
                            Messages.ShowWarning(Localization.GetString("WarningONLYCREATORCANCHANGE", this.LocalResourceFile));
                            break;

                        case TaskSubTaskController.UpdateStatus.SUBTASKNOTVALID:
                            Messages.ShowWarning(Localization.GetString("WarningSUBTASKNOTVALID", this.LocalResourceFile));
                            break;

                        default:
                            Exceptions.LogException(exc);
                            Messages.ShowError(Localization.GetString("ErrorUpdateTaskSubTask", this.LocalResourceFile));
                            break;
                    }
                }
            }
            catch (Exception exc)
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }

        /// <summary>
        /// Prepares for the edition of a time entry
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void lnkEdit_Click(object sender, EventArgs e)
        {
            try
            {
                using (UnitOfWork uof = new UnitOfWork(PortalId, ModuleId))
                {
                    TaskSubTaskController taskSubTaskController = new TaskSubTaskController(uof, TaskId.Value);
                    _TaskSubTask taskSubtask = taskSubTaskController.Get(Convert.ToInt32((sender as LinkButton).CommandArgument));
                    TaskName = taskSubtask.Name;
                    SubTaskId = taskSubtask.Id;

                    FillTaskSubTasks(uof, taskSubTaskController);
                }
            }
            catch (Exception exc)
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }

        /// <summary>
        /// Deletes the passed task time entry
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void lnkDelete_Click(object sender, EventArgs e)
        {
            try
            {
                using (UnitOfWork uof = new UnitOfWork(PortalId, ModuleId))
                {
                    TaskSubTaskController taskSubTaskController = new TaskSubTaskController(uof, TaskId.Value);
                    _TaskSubTask taskSubTask = new _TaskSubTask
                    {
                        Id = Convert.ToInt32((sender as LinkButton).CommandArgument),
                        ParentTaskId = TaskId.Value
                    };

                    using (TransactionScope scope = new TransactionScope())
                    {
                        taskSubTaskController.Delete(taskSubTask);
                        scope.Complete();
                    }
                    FillTaskSubTasks(uof, taskSubTaskController);
                    Messages.ShowSuccess(Localization.GetString("DeleteSuccess", this.LocalResourceFile));
                }
            }
            catch (TaskTimeValidationException exc)
            {
                TaskSubTaskController.DeleteStatus status =
                    (TaskSubTaskController.DeleteStatus)Enum.Parse(typeof(TaskSubTaskController.DeleteStatus), exc.ErrorCode().ToString());

                switch (status)
                {
                    case TaskSubTaskController.DeleteStatus.CURRENTUSERNOTMEMBER:
                        Messages.ShowWarning(Localization.GetString("WarningCURRENTUSERNOTMEMBER", this.LocalResourceFile));
                        break;

                    case TaskSubTaskController.DeleteStatus.ONLYCREATORCANDELETE:
                        Messages.ShowWarning(Localization.GetString("WarningONLYCREATORCANDELETE", this.LocalResourceFile));
                        break;

                    default:
                        Exceptions.LogException(exc);
                        Messages.ShowError(Localization.GetString("ErrorDeleteTaskSubTask", this.LocalResourceFile));
                        break;
                }
            }
            catch (Exception exc)
            {
                Exceptions.ProcessModuleLoadException(this, exc);
            }
        }

        #endregion "Events"

        #region "Aux Functions"

        /// <summary>
        /// Fills the language data into the respective controls
        /// </summary>
        private void FillLanguages()
        {
            btn_addTask.Text = Localization.GetString("btn_addTask", this.LocalResourceFile);
            btn_clearTask.Text = Localization.GetString("btn_clearTask", this.LocalResourceFile);
        }

        /// <summary>
        /// Gets the task sub tasks and binds them into the respective controls
        /// </summary>
        /// <param name="taskId"> the task to collect sub tasks from</param>
        private void BindTaskSubTasks(int taskId)
        {
            //fill existing task sub tasks
            using (UnitOfWork uof = new UnitOfWork(PortalId, ModuleId))
            {
                TaskSubTaskController taskSubTasksController = new TaskSubTaskController(uof, taskId);
                FillTaskSubTasks(uof, taskSubTasksController);
            }
        }

        /// <summary>
        /// Fills the list view of sub tasks entries controller
        /// </summary>
        /// <param name="uof">unit of work</param>
        /// <param name="taskTimeController">task sub task controller</param>
        private void FillTaskSubTasks(UnitOfWork uof, TaskSubTaskController taskSubTaskController)
        {
            lst_subtasks.DataSource = taskSubTaskController.GetAll();
            lst_subtasks.DataBind();
        }

        /// <summary>
        /// Clears the controls for update/create a sub task
        /// </summary>
        private void ClearSubTaskControl()
        {
            SubTaskId = null;
            TaskName = string.Empty;
        }

        #endregion "Aux Functions"
    }
}